/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.mushroom.website.web;

import cz.muni.fi.pa165.mushroom.website.dto.ForestDto;
import cz.muni.fi.pa165.mushroom.website.dto.GathererDto;
import cz.muni.fi.pa165.mushroom.website.dto.MushroomDto;
import cz.muni.fi.pa165.mushroom.website.dto.VisitDto;
import cz.muni.fi.pa165.mushroom.website.servicesImpl.ForestServiceImpl;
import cz.muni.fi.pa165.mushroom.website.servicesImpl.GathererServiceImpl;
import cz.muni.fi.pa165.mushroom.website.servicesImpl.MushroomServiceImpl;
import cz.muni.fi.pa165.mushroom.website.servicesImpl.VisitServiceImpl;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.stripes.action.Before;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.HandlesEvent;
import net.sourceforge.stripes.action.LocalizableMessage;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import org.apache.shiro.SecurityUtils;


/**
 * Action bean for visit
 * 
 * @author Roman Jakubco <roman.jakubco@gmail.com>
 */
public class VisitActionBean extends BasicActionBean{
    
    @SpringBean
    protected VisitServiceImpl visitServiceImpl;
    
    @SpringBean
    protected ForestServiceImpl forestServiceImpl;
    
    @SpringBean
    protected MushroomServiceImpl mushroomServiceImpl;
    
    @SpringBean
    protected GathererServiceImpl gathererServiceImpl;   
 
    
    
    @ValidateNestedProperties(value = {        
        @Validate(on = {"add", "save"}, field = "forestDto", required = true),        
        @Validate(on = {"add", "save"}, field = "mushrooms", required = false),
        @Validate(on = {"add", "save"}, field = "info", required = true)
    })
    private VisitDto visitDto;
    
    private GathererDto gathererDto;
    
    private ForestDto forestDto;
//    
    private List<MushroomDto> mushrooms;
    
    private List<VisitDto> myVisit;
    
    private List<VisitDto> visitsTest;
    
    
    @DefaultHandler
    public Resolution all() {
        this.visitsTest = visitServiceImpl.listVisits();
        return new ForwardResolution("/listVisits.jsp");
    }
    
    @Before(stages = LifecycleStage.BindingAndValidation, on = {"edit", "save", "delete"})
    public void loadForestFromDatabase() {
        String ids = getContext().getRequest().getParameter("forestDto.id");

        if (ids == null) {
            ids = getContext().getRequest().getParameter("visitDto.forestDTO");
        }

        if (ids == null || ids.equals("")) {
            return;
        }
        forestDto = forestServiceImpl.findForest(Long.parseLong(ids));
    }
    
    @Before(stages = LifecycleStage.BindingAndValidation, on = {"edit", "save", "delete"})
    public void loadMushroomsFromDatabase() {
        String[] mushroomIds = getContext().getRequest().getParameterValues("visitDto.mushrooms");             

        if (mushroomIds == null || (mushroomIds.length == 0) ) {
            return;
        }
        List<MushroomDto> temp = new ArrayList<>();
        
        for(String id : mushroomIds){
            temp.add(mushroomServiceImpl.findMushroom(Long.parseLong(id)));            
        }
        mushrooms = temp;
    }
    
    @Before(stages = LifecycleStage.BindingAndValidation, on = {"edit", "save", "delete"})
    public void loadGathererFromDatabase() {
        String ids = getContext().getRequest().getParameter("gathererDto.id");

        if (ids == null) {
            ids = getContext().getRequest().getParameter("visitDto.gathererDTO");
        }

        if (ids == null || ids.equals("")) {
            return;
        }
        gathererDto = gathererServiceImpl.findGatherer(Long.parseLong(ids));
    }
    
    public Resolution add(){
        String forestId = getContext().getRequest().getParameter("visitDto.forestDto");
        String gathererId = getContext().getRequest().getParameter("visitDto.gathererDto");        
        
        List<MushroomDto> mushroomDtos = new ArrayList();
        ForestDto tempForestDto;
        GathererDto tempGathererDto;
        MushroomDto test;
        try {
            tempForestDto = forestServiceImpl.findForest(Long.parseLong(forestId));
            tempGathererDto = gathererServiceImpl.findGathererByUsername((String)SecurityUtils.getSubject().getPrincipal());
            if(getContext().getRequest().getParameterValues("visitDto.mushrooms") != null){
                for(String s : getContext().getRequest().getParameterValues("visitDto.mushrooms")){
                    mushroomDtos.add(mushroomServiceImpl.findMushroom(Long.parseLong(s)));
            
                }
            }           
            
        } catch (IllegalArgumentException ex) {
            return new RedirectResolution(this.getClass(), "all");
        }
        visitDto.setForestDto(tempForestDto);
        visitDto.setGathererDto(tempGathererDto); 
        if(!mushroomDtos.isEmpty()){
            visitDto.getMushrooms().addAll(mushroomDtos);
        }
        
        
        visitServiceImpl.createVisit(visitDto);
        getContext().getMessages().add(new LocalizableMessage("visit.add.message")); 
        return new ForwardResolution("/protected/showMyVisits.jsp");       
       
    }
    
    public Resolution delete(){
        String forestId = getContext().getRequest().getParameter("forestDto.id");
        String gathererId = getContext().getRequest().getParameter("gathererDto.id");       
   
        ForestDto forestDto;
        GathererDto gathererDto;
        try {
            forestDto = forestServiceImpl.findForest(Long.parseLong(forestId));
            gathererDto = gathererServiceImpl.findGathererByUsername((String)SecurityUtils.getSubject().getPrincipal());
        } catch (IllegalArgumentException ex) {
            return new RedirectResolution(this.getClass(), "all");
        }
        visitDto.setForestDto(forestDto);
        visitDto.setGathererDto(gathererDto);       
        
        visitServiceImpl.deleteVisit(this.visitDto);
        getContext().getMessages().add(new LocalizableMessage("visit.delete.message")); 
        return new ForwardResolution("/protected/showMyVisits.jsp");
    }
    
    public Resolution edit(){
        return new ForwardResolution("/protected/editVisit.jsp");
    }
    
    public Resolution save(){            
        String forestId = getContext().getRequest().getParameter("visitDto.forestDto");
        String gathererId = getContext().getRequest().getParameter("visitDto.gathererDto");
        
        ForestDto forestDto;
        GathererDto gathererDto;
        try {
            forestDto = forestServiceImpl.findForest(Long.parseLong(forestId));
            gathererDto = gathererServiceImpl.findGathererByUsername((String)SecurityUtils.getSubject().getPrincipal());
        } catch (IllegalArgumentException ex) {
            return new RedirectResolution(this.getClass(), "all");
        }
        visitDto.setForestDto(forestDto);
        visitDto.setGathererDto(gathererDto);
        visitDto.setMushrooms(mushrooms);
        visitServiceImpl.updateVisit(visitDto);
        getContext().getMessages().add(new LocalizableMessage("visit.update.message")); 
        return new ForwardResolution("/protected/showMyVisits.jsp");

    }
    
    public Resolution cancel(){
        return new RedirectResolution(this.getClass(), "all"); 
    }
    
    @Before(stages = LifecycleStage.BindingAndValidation, on = {"edit", "save"})
    public void loadVisitFromDatabase() {
        String ids = getContext().getRequest().getParameter("visitDto.id");
        if (ids == null) return;
       visitDto = visitServiceImpl.findVisit(Long.parseLong(ids));
    }      
    
    public List<VisitDto>  showVisitsByGatherer(){        
        GathererDto gathererDto;
        gathererDto = gathererServiceImpl.findGathererByUsername((String)SecurityUtils.getSubject().getPrincipal());
        List<VisitDto> temp = visitServiceImpl.listVisitsByGatherer(gathererDto);
        return temp;
    }
    
    public Resolution showVisitsByForest(){ 
        String forestId = getContext().getRequest().getParameter("forestDto.id");          
        ForestDto fd = forestServiceImpl.findForest(Long.parseLong(forestId));    
        List<VisitDto> temp = visitServiceImpl.listVisitsByForest(fd);    
        this.visitsTest = temp;     
        return new ForwardResolution("/listVisits.jsp"); 
    }
    
    @HandlesEvent("showVisits")
    public Resolution showVisits(){
        this.visitsTest = visitServiceImpl.listVisits();
        return new ForwardResolution("/listVisits.jsp");
    }
    
    
    
    public List<VisitDto> findAllVisitDto(){
        return visitServiceImpl.listVisits();
    }
    public List<VisitDto> getVisit(){
        return visitServiceImpl.listVisits();
    }
    
    
    public VisitDto getVisitDto() {
        return visitDto;
    }

    public void setVisitDto(VisitDto visitDto) {
        this.visitDto = visitDto;
    }

    public List<MushroomDto> getMushrooms() {
        return mushrooms;
    }

    public void setMushrooms(List<MushroomDto> mushrooms) {
        this.mushrooms = mushrooms;
    }

    public GathererDto getGathererDto() {
        return gathererDto;
    }

    public void setGathererDto(GathererDto gathererDto) {
        this.gathererDto = gathererDto;
    }

    public ForestDto getForestDto() {
        return forestDto;
    }

    public void setForestDto(ForestDto forestDto) {
        this.forestDto = forestDto;
    }

    public List<VisitDto> getMyVisit() {        
        this.myVisit = showVisitsByGatherer();
        return myVisit;
    }

    public void setMyVisit(List<VisitDto> myVisit) {        
        this.myVisit = showVisitsByGatherer();
    }

    public List<VisitDto> getVisitsTest() {
        String forestId = getContext().getRequest().getParameter("forestDto.id");
        if(forestId != null){
            showVisitsByForest();
        }      
        
        return visitsTest;
    }

    public void setVisitsTest(List<VisitDto> visits) {
        this.visitsTest = visits;
    } 

    
}
